/**
 * Copyright (C) 2010, 2011 Neofonie GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.dicodeproject.twitterstream.util;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides access to application configuration variables.
 */
public final class TwitterHarvesterCFGBuilder {
  /** Logger for this class. */
  private static final Logger log = LoggerFactory.getLogger(TwitterHarvesterCFGBuilder.class);

  public static final String DEFAULT_PROPERTIES_FILENAME = "eu.dicode.twitterharvester.properties";

  /**
   * Parse command line arguments and store the results for future use.
   * 
   * @param args
   *          the command line arguments to parse.
   * @return the java bean holding all command line arguments.
   * */
  @SuppressWarnings("static-access")
  static Configuration buildConfiguration(String[] args) {
    Option propertiesFileOption = OptionBuilder.withArgName("p").hasArg().withLongOpt("properties")
	.withDescription("Full qualified name of twitter harvester's property file.").create("p");
    Option helpOption = OptionBuilder.withDescription("Print usage message and exit.").create("help");
    Options options = new Options();
    options.addOption(propertiesFileOption);
    options.addOption(helpOption);

    CommandLineParser parser = new GnuParser();

    PropertiesConfiguration cmdLineCFG = null;
    if (args != null) {
      try {
	CommandLine line = parser.parse(options, args);
	if (line.hasOption("help")) {
	  HelpFormatter formatter = new HelpFormatter();
	  formatter.printHelp("command", options);
	  System.exit(1);
	}
	if (line.hasOption("p")) {
	  String propFilename = line.getOptionValue("p");
	  if (propFilename == null) {
	    throw new ParseException("Full qualified name of twitter harvester's property file must not be null.");
	  } else {
	    try {
	      cmdLineCFG = new PropertiesConfiguration(propFilename);
	    } catch (ConfigurationException e) {
	      throw new ParseException(e.getMessage());
	    }
	  }
	}
      } catch (ParseException e) {
	log.error("Parsing failed. Details: " + e.getMessage(), e);
	HelpFormatter formatter = new HelpFormatter();
	formatter.printHelp("command", options);
	System.exit(1);
      }
    }

    CompositeConfiguration cc = null;
    try {
      if (cmdLineCFG == null) {
	return new PropertiesConfiguration(DEFAULT_PROPERTIES_FILENAME);
      } else {
	cc = new CompositeConfiguration();
	cc.addConfiguration(cmdLineCFG);
	cc.addConfiguration(new PropertiesConfiguration(DEFAULT_PROPERTIES_FILENAME));
      }
    } catch (ConfigurationException e) {
      log.error("Unable to load configuration. Details: " + e.getMessage(), e);
      System.exit(2);
    }
    return cc;
  }
}
